import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import paskal.abstractplayer.AbstractPlayer;
import paskal.ui.components.Button;
import paskal.ui.components.Label;
import paskal.ui.components.Panel;
import paskal.ui.components.ProgressSlider;
import paskal.ui.components.Slider;

public class PlayerPanel extends Panel {
	private static final long serialVersionUID = 7698860604617429267L;

	private SimpleDateFormat dateFormat = new SimpleDateFormat("mm:ss");
	private boolean isRewind = false;
	private AbstractPlayer player;
	private Label cashingLabel;
	private Button play;
	private Button pause;
	private Button next;
	private Button playlist;
	private ProgressSlider slider;
	private Slider volume;
	private Label timeTitle;
	private Label durationTitle;
	private Label trackTitle;
	private Label volumeLabel;
	private Label muteLabel;
	private int oldVolumeValue = 90;
	private boolean isMute = false;

	public PlayerPanel(AbstractPlayer player) {
		this.player = player;
		setLayout(null);
		stylize("playerPanel");
		init();
	}

	private void init() {
		trackTitle = new Label("RelaxPlayer");
		trackTitle.stylize("trackLabel");
		add(trackTitle);

		final MouseAdapter muteVolumeAdapter = new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (isMute) {
					muteLabel.setVisible(false);
					volumeLabel.setVisible(true);
					volume.setValue(oldVolumeValue);
					isMute = false;
				} else {
					muteLabel.setVisible(true);
					volumeLabel.setVisible(false);
					oldVolumeValue = volume.getValue();
					volume.setValue(0);
					isMute = true;
				}
			}
		};
		volumeLabel = new Label();
		volumeLabel.stylize("volumeLabel");
		volumeLabel.addMouseListener(muteVolumeAdapter);
		add(volumeLabel);

		muteLabel = new Label();
		muteLabel.stylize("muteLabel");
		muteLabel.setVisible(false);
		muteLabel.addMouseListener(muteVolumeAdapter);
		add(muteLabel);

		volume = new Slider();
		volume.stylize("volumeSlider");
		volume.setValue(oldVolumeValue);
		volume.setMaximum(100);
		volume.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent e) {
				player.setVolume((float) volume.getValue() / 100);
				if (volume.getValueIsAdjusting()) {
					if (isMute) {
						volumeLabel.setVisible(true);
						muteLabel.setVisible(false);
						isMute = false;
					} else if (volume.getValue() == 0) {
						volumeLabel.setVisible(false);
						muteLabel.setVisible(true);
						isMute = true;
					}
				}
			}
		});
		volume.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				volume.setValue((int) ((double) e.getX() / volume.getWidth() * volume
						.getMaximum()));
			}
		});
		add(volume);

		timeTitle = new Label("00:00");
		timeTitle.stylize("timeLabel");
		add(timeTitle);

		durationTitle = new Label("00:00");
		durationTitle.stylize("durationLabel");
		add(durationTitle);

		slider = new ProgressSlider();
		slider.stylize("trackSlider");
		slider.stylize("Slider");
		slider.setValue(0);
		slider.setMaximum(slider.getWidth());
		slider.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				super.mouseReleased(e);
				if (isRewind) {
					player.setPercentagePosition(slider.getValue() * 1.0
							/ slider.getMaximum());
					isRewind = false;
				}
			}

			@Override
			public void mousePressed(MouseEvent e) {
				slider.setValue((int) ((double) e.getX() / slider.getWidth() * slider
						.getMaximum()));
			}
		});
		slider.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent e) {
				if (slider.getValueIsAdjusting()) {
					isRewind = true;
				}
			}
		});
		add(slider);

		Button previous = new Button();
		previous.stylize("previousButton");
		previous.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent event) {
				player.previous();
			}
		});
		add(previous);

		play = new Button();
		play.stylize("playButton");
		play.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				player.play();
			}
		});
		add(play);

		pause = new Button();
		pause.stylize("pauseButton");
		pause.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				player.pause();
			}
		});
		pause.setVisible(false);
		add(pause);

		next = new Button();
		next.stylize("nextButton");
		next.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				player.next();
			}
		});
		add(next);

		playlist = new Button();
		playlist.stylize("playlistButton");
		playlist.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (Main.isPlaylistVisible()) {
					Main.getInstance().hidePlaylist();
				} else {
					Main.getInstance().showPlaylist();
				}
			}
		});
		add(playlist);

		Button closeButton = new Button();
		closeButton.stylize("closeButton");
		closeButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Main.getInstance().dispose();
			}
		});
		add(closeButton);

		cashingLabel = new Label();
		cashingLabel.stylize("cashingLabel");
		cashingLabel.setVisible(false);
		add(cashingLabel);

	}

	public void clickPlay() {
		play.doClick();
	}

	public void clickNext() {
		next.doClick();
	}

	public void updateTimeLabel(int time) {
		String text = dateFormat.format(time * 1000);
		timeTitle.setText(text);
	}

	public void updateDurationLabel(int time) {
		String text = dateFormat.format(time * 1000);
		durationTitle.setText(text);
	}

	public void updateTrackLabel(String text) {
		trackTitle.setText(text);
	}

	public void updateSliderValue(int time) {
		if (!isRewind) {
			slider.setValue(time);
		}
	}

	public void updatePVolumeValue(float p) {
		volume.setValue((int) (p * 100));
	}

	public float getPVolumeValue() {
		return volume.getValue() / 100f;
	}

	public int getSliderMaximum() {
		return slider.getMaximum();
	}

	public void setPauseVisible() {
		pause.setVisible(true);
		play.setVisible(false);
	}

	public void setPlayVisible() {
		pause.setVisible(false);
		play.setVisible(true);
	}

	public void setLoadedPercentage(double loadedPercentage) {
		slider.setLoadedPercentage(loadedPercentage);
	}

	public void showCashing(boolean value) {
		cashingLabel.setVisible(value);
		slider.setVisible(!value);
	}
}